<template>
    <div class="wrap h-100">
        <div class="w-100 code-editor" :ref="generateId"></div>
        <span v-if="withFullscreenBtn" title="全屏显示">
      <svg-icon
              class="icon-fullscreen"
              icon-class="fullscreen"
              :style="{ bottom: (withFooterBtns ? 47 : 10) + 'px' }"
              @click.native="fullscreen"
      ></svg-icon>
    </span>

        <el-dialog
                ref="dialog"
                custom-class="code-dialog"
                :visible.sync="isVisible"
                title="脚本编辑"
                fullscreen
                append-to-body
                :show-footer="false"
                @close="closeEditCode"
        >
            <code-editor v-model="dialogValue"></code-editor>
        </el-dialog>
    </div>
</template>
<script>
    // 引入全局实例
    import ace from 'ace-builds'
    // 主题风格，引入主题后还需要在 options 中指定主题才会生效
    import 'ace-builds/src-min-noconflict/theme-monokai'
    import 'ace-builds/src-min-noconflict/theme-dracula'
    // 支持代码格式， 需要引入具体的语法高亮库才会有对应的语法高亮效果
    import 'ace-builds/src-min-noconflict/mode-javascript'
    import 'ace-builds/src-min-noconflict/mode-json'
    import 'ace-builds/src-min-noconflict/mode-css'
    import 'ace-builds/src-min-noconflict/mode-java'
    import 'ace-builds/src-min-noconflict/mode-groovy'
    import 'ace-builds/src-min-noconflict/ext-language_tools'
    // import groovyWorkerUrl from 'file-loader!ace-builds/src-noconflict/worker-groovy'
    import jsWorkerUrl from 'file-loader!ace-builds/src-noconflict/worker-javascript'
    import jsonWorkerUrl from 'file-loader!ace-builds/src-noconflict/worker-json'
    import cssWorkerUrl from 'file-loader!ace-builds/src-noconflict/worker-css'
    // import javaWorkerUrl from 'file-loader!ace-builds/src-noconflict/worker-java'
    ace.config.setModuleUrl('ace/mode/javascript_worker', jsWorkerUrl)
    ace.config.setModuleUrl('ace/mode/json_worker', jsonWorkerUrl)
    ace.config.setModuleUrl('ace/mode/css_worker', cssWorkerUrl)
    // ace.config.setModuleUrl('ace/mode/groovy_worker', groovyWorkerUrl)
    ace.config.setModuleUrl(
        'ace/snippets/javascript',
        require('file-loader!ace-builds/src-noconflict/snippets/javascript.js')
    )
    ace.config.setModuleUrl('ace/snippets/css', require('file-loader!ace-builds/src-noconflict/snippets/css.js'))

    export default {
        name: 'code-editor',
        model: {
            event: 'change'
        },
        props: {
            // 编辑器内容
            value: String,
            // 默认语言
            language: {
                type: String,
                default: 'javascript'
            },
            // 主题，对应主题库 JS 需要提前引入
            theme: {
                tyle: String,
                default: 'monokai'
            },
            // 是否只读
            readonly: {
                type: Boolean,
                default: false
            },
            // 最大行数
            maxLines: Number,
            // 是否显示全屏按钮
            withFullscreenBtn: {
                type: Boolean,
                default: false
            },
            withFooterBtns: {
                type: Boolean,
                default: false
            }
        },
        data() {
            return {
                editor: null,
                generateId:
                    'id_' +
                    Math.random()
                        .toString(36)
                        .substr(2, 4),
                isVisible: false,
                dialogValue: ''
            }
        },
        mounted() {
            // 初始化
            this.initEditor()
        },
        watch: {
            value(val) {
                if (this.editor.getValue() !== val) {
                    this.editor.setValue(val)
                    this.editor.clearSelection()
                }
            }
        },
        methods: {
            // 初始化
            initEditor() {
                // 创建实例
                this.editor = ace.edit(this.$refs[this.generateId], {
                    mode: `ace/mode/${this.language}`,
                    theme: `ace/theme/${this.theme}`,
                    fontSize: 12,
                    tabSize: 2,
                    value: this.value,
                    selectionStyle: 'text',
                    maxLines: this.maxLines,
                    readOnly: this.readonly
                })
                // 设置属性等，具体需要可根据官方参数自行设置
                this.editor.setOptions({
                    enableBasicAutocompletion: true,
                    enableSnippets: true,
                    enableLiveAutocompletion: true,
                    wrap: true,
                    setShowPrintMargin: false
                })
                // 设置值改变监听
                this.editor.on('change', () => {
                    this.$emit('change', this.editor.getValue())
                })
            },
            // 实例方法，高亮某一行
            gotoLine(lineNumber) {
                this.editor.gotoLine(lineNumber)
            },
            // 全屏编辑
            fullscreen() {
                this.dialogValue = JSON.parse(JSON.stringify(this.editor.getValue()))
                this.isVisible = true
            },
            closeEditCode() {
                this.editor.setValue(this.dialogValue)
                this.editor.clearSelection()
            },
            // resize编辑器
            resize() {
                this.editor.resize(true)
            },
            destroy() {
                if (this.editor) {
                    this.editor.destroy()
                    this.editor = null
                }
            }
        },
        beforeDestroy() {
            this.destroy()
        }
    }
</script>
<style lang="scss" scoped>
    .h-100{
        height: 80%;
    }
    .wrap {
        position: relative;
        .code-editor {
            min-height: 200px;
            height: 100%;
            border: 1px solid #282f3a;
            background-color: #0e1013;
        }
        .icon-fullscreen {
            position: absolute;
            // color: #fff;
            right: 10px;
            font-size: 16px;
            z-index: 9999;
            cursor: pointer;
        }
    }
    /deep/ .code-dialog {
        &::before {
            content: '';
            position: absolute;
            display: block;
            top: 0;
            left: 0;
            right: 0;
            width: 100%;
            height: 2px;
            background-image: linear-gradient(270deg, #00deff, #2483ff 74%);
        }
        display: flex;
        flex-direction: column;
        background-color: #303640;
        .el-dialog__header {
            border: none;
            .el-dialog__title {
                color: #ccc;
            }
        }
        .el-dialog__body {
            flex: 1 1 0;
            padding-top: 10px;
        }
    }
</style>

